import { HTTPError } from 'got';

import {
  type CreateConnector,
  type GetConnectorConfig,
  type SendMessageFunction,
  type SmsConnector,
  ConnectorError,
  ConnectorErrorCodes,
  ConnectorType,
  validateConfig,
} from '@logto/connector-kit';

import { defaultMetadata } from './constant.js';
import { sendSmsRequest } from './http.js';
import { SmsConfigGuard } from './schema.js';

const sendMessage =
  (getConfig: GetConnectorConfig): SendMessageFunction =>
  async (data, inputConfig) => {
    // 手机号、类型、验证码负载
    const { to, type, payload } = data;
    // 校验配置
    const config = inputConfig ?? (await getConfig(defaultMetadata.id));
    validateConfig(config, SmsConfigGuard);
    const { Templates, ...filteredConfig } = config;
    const template =
      Templates.find(({ usageType }) => usageType === type) ??
      Templates.find(({ usageType }) => usageType === 'Generic');

    if (!template) {
      throw new ConnectorError(
        ConnectorErrorCodes.TemplateNotFound,
        `Cannot find template for type: ${type}, nor Generic template.`
      );
    }

    // 从payload中筛选出短信参数
    const { locale, ...filteredPayload } = payload;
    const parametersSet = Object.values(filteredPayload).map(String);

    try {
      const httpResponse = await sendSmsRequest(
        template.templateCode,
        parametersSet,
        to,
        filteredConfig
      );

      const { body } = httpResponse;

      if (body.status !== '00') {
        throw new ConnectorError(ConnectorErrorCodes.General, `${body.status}: ${body.message}`);
      }

      return httpResponse;
    } catch (error) {
      if (!(error instanceof HTTPError)) {
        throw error;
      }

      const { message } = error;

      throw new ConnectorError(ConnectorErrorCodes.General, `Request error: ${message}`);
    }
  };

const createShlianluSmsConnector: CreateConnector<SmsConnector> = async ({ getConfig }) => ({
  metadata: defaultMetadata,
  type: ConnectorType.Sms,
  configGuard: SmsConfigGuard,
  sendMessage: sendMessage(getConfig),
});

export default createShlianluSmsConnector;
